package com.snail.jj.androiddemos.components;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;

import com.snail.jj.androiddemos.R;
import com.snail.jj.androiddemos.bases.BaseActivity;
import com.snail.jj.androiddemos.beans.Dog;

/**
 * Created by snail on 2017/4/26.
 */

/**
 * Activity的四种启动模式
 *
 * 1.standard 标准启动模式
 * 2.singleTop 单一顶部模式
 *  a.如果任务栈的栈顶存在这个要开启的activity,不会重新的创建activity,而是复用已经存在的
 *    activity.保证栈顶如果存在,不会重复创建.
 *  b.应用场景:浏览器的书签
 * 3.singleTask 单一任务栈,在当前任务栈里面只能有一个实例存在
 *  a.当开启activity的时候,就去检查在任务栈里面是否有实例已经存在,如果有实例存在就复用这个已经存在的activity,
 *    并且把这个activity上面的所有的别的activity都清空,复用这个已经存在的activity.保证整个任务栈里面只有一个
 *    实例存在.
 *  b.应用场景:浏览器的activity
 *  c.如果一个activity的创建需要占用大量的系统资源(cpu,内存) 一般配置这个activity为singletask的启动模式
 * 4.singleInstance启动模式非常特殊,activity会运行在自己的任务栈里面,并且这个任务栈里面只有一个实例存在
 *  a.如果你要保证一个activity在整个手机操作系统里面只有一个实例存在,使用singleInstance
 *  b.应用场景:电话拨打界面
 *
 */

public class ActivityActivity extends BaseActivity{

    private final static String TAG = "ActivityActivity";


    /**
     * Activity被创建完毕
     * 当活动第一次启动的时候,触发该方法,可以在此时完成活动的初始化工作.
     * onCreate方法有一个参数,该参数可以为空null,
     * 也可以是之前调用onSaveInstanceState()方法保存的状态信息
     * @param savedInstanceState
     */
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.i(TAG,"onCreate");
        setContentView(R.layout.activity_activity);
        initView();

        if (savedInstanceState != null) {
            savedInstanceState.getString("name");
        }

    }


    //=====================由于内存不足导致的Activity被杀死=================================
    /**
     * 当activity由于内存不足,被系统杀死后会调用onSaveInstanceState和onRestoreInstanceState
     * 保存和恢复试图.按照优先级从高到低,将activity分为以下三种:
     * 1. 前台Activity
     * 2. 可见但非后台Activity
     * 3. 后台Activity
     */
    /**
     * 当Activity被杀死而重新创建,系统通过调用此方法保存状态
     *
     * onRestoreInstanceState 恢复试图状态
     *
     * @param outState
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("name","Snail");
    }

    /**
     * 在onStart之后执行
     * @param savedInstanceState
     */
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        String name = savedInstanceState.getString("name");
        Log.i(TAG,name);
    }

    public void initView() {
        setTitleBarTitle("四大组件之活动");
        setRightViewVisiable(View.VISIBLE);
    }


    /**
     * 该方法的触发表示所属活动将被展现给用户.Activity已经显示在屏幕,
     * 但没有得到焦点
     */
    @Override
    protected void onStart() {
        super.onStart();
    }

    /**
     * Activity得到焦点,可以与用户交互
     */
    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG,"onResume");
    }

    /**
     * 当处于停止状态的活动需要再次展现给用户的时候,
     * 触发该方法,即从不可见变成可见时会执行此方法
     */
    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i(TAG,"onRestart");
    }

    /**
     * Activity被销毁
     * 当活动销毁的时候,触发该方法.和onStop方法一样,如果内存
     * 紧张,系统会直接结束这个活动而不会触发该方法
     * onSaveInstanceState:系统调用该方法,允许活动保存之前的状态,
     * 比如说在一串字符串中的光标所处的位置等
     * 通常情况下,开发者不需要重写覆盖该方法,在默认的实现中,已经提供了自动
     * 保存活动所涉及到的用户界面组件的所有状态信息
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG,"onDestroy");
    }

    /**
     * Activity失去焦点,无法再与用户交互,但依然可见
     * 当一个正在前台运行的活动因为其他活动需要前台运行
     * 而转入后台运行的时候,触发该方法.这时候需要将活动的状态持久化,比
     * 如正在编辑的数据库记录等
     */
    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG,"onPause");
    }

    /**
     * Activity不可见,进入后台
     * 当一个活动不再需要展示给用户的时候,触发该方法.如果内存紧张,系统会
     * 直接结束这个活动,而不会触发onStop方法,所以保存状态信息是应该在onPause
     * 时做,而不是onStop时做.活动如果没有在前台运行,都将被停止或者Linux管理
     * 进程为了给新的活动预留足够的存储空间而随时结束这些活动.因此对于开发者来说,
     * 在设计应用程序的时候,必须时刻牢记这一原则.在一些情况下,onPause方法或许
     * 是活动触发的最后的方法,因此开发者需要在这个时候保存需要保存的信息.
     */
    @Override
    protected void onStop() {
        super.onStop();
        Log.i(TAG,"onStop");
    }



    /**
     *  Activity的跳转
     *  1.Activity的跳转需要创建Intent对象,通过设置intent对象的参数指定要跳转的activity
     *  2.通过设置Activity的包名和类名实现跳转,称为显式意图
     *  3.通过指定动作实现跳转,称为隐式跳转
     */

    // 1.显式跳转
    public void explicit() {
        /**
        Intent intent = new Intent();
        intent.setClass(this,ActivityActivity.class);
        startActivity(intent);
         */

        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        Uri content_url = Uri.parse("http://www.baidu.com");
        intent.setData(content_url);
        intent.setClassName("com.android.browser","com.android.browser.BrowserActivity");
        startActivity(intent);

    }

    // 2.跳转至其他应用的Activity
    public void gotoOtherApp() {
        Uri uri = Uri.parse("tel:13486171976");
        Intent intent = new Intent(Intent.ACTION_DIAL,uri);
        startActivity(intent);
    }

    // 3.隐式跳转Activity
    public void hh() {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_DIAL);
        startActivity(intent);
    }


    /**
     * Activity跳转时的数据传递
     * 1.Intent传递简单数据
     * 2.Bundle传递数据包
     * 3.传递值对象
     */

    // 1.传递简单数据
    public void sendJDData() {
        Intent intent = new Intent(this,TestActivity.class);
        intent.putExtra("name","Snail");
        startActivity(intent);
    }

    // 2.Bundle传递数据包
    public void sendBundleData() {
        Intent intent = new Intent(this,TestActivity.class);
        Bundle bundle = new Bundle();
        bundle.putString("name","Snail");

        intent.putExtras(bundle);
        startActivity(intent);
    }

    // 3.自定义对象的传递
    public void sendBeanData() {
        // 实现Serializable接口的对象
//        Intent intent = new Intent(this,TestActivity.class);
//        intent.putExtra("Person",new Person("snail",24));
//        startActivity(intent);

        // 实现Parcelable接口的对象
        Intent intent = new Intent(this,TestActivity.class);
        intent.putExtra("Dog",new Dog("DaoDao",12));
        startActivity(intent);


    }


    // 4.获取Activity的返回参数
    public void fHData() {
        Intent intent = new Intent(this,TestActivity.class);
        intent.putExtra("Dog",new Dog("DaoDao",12));
        startActivityForResult(intent,100);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == 5) {
            Log.i(TAG,Integer.toString(requestCode));
        }
    }

    @Override
    public void rightViewAction() {
        super.rightViewAction();
        fHData();
    }
}

/**
 * 利用Android 提供的Parcelable 传递数据
 *
 * 实现Parcelable步骤
 * 1.implements Parcelable
 * 2.重写writeToParcel方法,将你的对象序列化为一个Parcel对象,即:将类的数据写入
 *   外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从Parcel容易获取数据
 * 3.重写describeContents方法,内容接口描述,默认返回0就可以
 * 4.实例化静态内部对象CREATOR实现接口Parcelable.Creator
 *
 *
 * Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传递时推荐使用Parcelable,如
 * activity间传输数据.而Serializable,因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable
 * 进行数据化持久.Serializable的作用是为了保存对象到本地文件 数据库 网络流 rmi以方便数据传输,当然这种传输可以是
 * 程序内的也可以是两个程序之间的.而Android的Parcelable的设计初衷是因为Serializable效率过慢,为了在程序内不同组件间
 * 以及不同Android程序间高效的传输数据而设计,这些数据仅在内存中存在,Parcelable是通过IBinder通信的消息的载体.
 *
 * 选择序列化方法的原则
 * 1).在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable.
 * 2).Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC.
 * 3).Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下.尽管
 * Serializable效率低点,但此时还是建议使用Serializable.
 *
 */



